/*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License
* Version 1.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://www.sun.com/
*
* The Original Code is Forte for Java, Community Edition. The Initial
* Developer of the Original Code is Sun Microsystems, Inc. Portions
* Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
*/
package org.netbeans.examples.modules.minicomposer;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.text.MessageFormat;
import java.util.*;
import java.util.List;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import javax.swing.text.*;
import org.openide.TopManager;
import org.openide.loaders.*;
import org.openide.text.EditorSupport;
import org.openide.util.*;
import org.openide.windows.*;
public class ScorePanel extends CloneableTopComponent implements PropertyChangeListener {
private MultiDataObject.Entry entry;
private ScoreCookie cookie;
private ScoreOpenSupport support;
private Score score;
private static final long serialVersionUID =7204432764586558961L;
/** For externalization only! */
public ScorePanel () {
}
public ScorePanel (MultiDataObject.Entry entry) {
super (entry.getDataObject ());
this.entry = entry;
init ();
}
protected CloneableTopComponent createClonedObject () {
return new ScorePanel (entry);
}
/**
* @serialData Super, then the MultiDataObject.Entry to represent. */
public void writeExternal (ObjectOutput oo) throws IOException {
super.writeExternal (oo);
oo.writeObject (entry);
}
/**
* @serialData #see writeExternal */
public void readExternal (ObjectInput oi) throws IOException, ClassNotFoundException {
super.readExternal (oi);
entry = (MultiDataObject.Entry) oi.readObject ();
init ();
}
public void open (Workspace ws) {
if (ws == null) ws = TopManager.getDefault ().getWindowManager ().getCurrentWorkspace ();
Mode mode = ws.findMode (EditorSupport.EDITOR_MODE);
if (mode != null) mode.dockInto (this);
super.open (ws);
}
protected boolean closeLast () {
if (support == null) {
System.err.println("WARNING: no ScoreOpenSupport, will just close");
return true;
}
boolean ok = support.canClose ();
return ok;
}
public void propertyChange (PropertyChangeEvent ev) {
if (DataObject.PROP_MODIFIED.equals (ev.getPropertyName ())) {
updateName ();
}
}
protected void updateName () {
DataObject obj = entry.getDataObject ();
String displayName = obj.getNodeDelegate ().getDisplayName ();
if (obj.isModified ()) {
setName (MessageFormat.format (NbBundle.getBundle (ScorePanel.class).getString ("LBL_modified_name"),
new Object[] { displayName }));
} else {
setName (displayName);
}
}
private void init () {
if (! SwingUtilities.isEventDispatchThread ()) {
SwingUtilities.invokeLater (new Runnable () {
public void run () {
init ();
}
});
return;
}
updateName ();
entry.getDataObject ().addPropertyChangeListener (WeakListener.propertyChange (this, entry.getDataObject ()));
setLayout (new BorderLayout ());
cookie = (ScoreCookie) entry.getDataObject ().getCookie (ScoreCookie.class);
if (cookie == null) {
JLabel label = new JLabel (NbBundle.getBundle (ScorePanel.class).getString ("LBL_cannot_load"));
label.setHorizontalAlignment (SwingConstants.CENTER);
add (label, BorderLayout.SOUTH);
return;
}
Task t = cookie.prepare ();
t.addTaskListener (new TaskListener () {
public void taskFinished (Task t2) {
SwingUtilities.invokeLater (new Runnable () {
public void run () {
init2 ();
}
});
}
});
JLabel label = new JLabel (NbBundle.getBundle (ScorePanel.class).getString ("LBL_loading"));
label.setHorizontalAlignment (SwingConstants.CENTER);
add (label, BorderLayout.SOUTH);
// Just for safety:
score = new Score (Collections.EMPTY_LIST, Collections.EMPTY_LIST, Collections.EMPTY_LIST);
support = (ScoreOpenSupport) entry.getDataObject ().getCookie (ScoreOpenSupport.class);
}
private void init2 () {
try {
score = cookie.getScore ();
} catch (IOException ioe) {
TopManager.getDefault ().notifyException (ioe);
return;
}
TableColumnModel columns = new DefaultTableColumnModel ();
TableColumn column = new TableColumn (0, 150, new PulldownRenderer (Score.TONES_LONG), new PulldownEditor (Score.TONES_LONG));
column.setHeaderValue (NbBundle.getBundle (ScorePanel.class).getString ("LBL_header_tone"));
columns.addColumn (column);
column = new TableColumn (1, 150, new PulldownRenderer (Score.OCTAVES_LONG), new PulldownEditor (Score.OCTAVES_LONG));
column.setHeaderValue (NbBundle.getBundle (ScorePanel.class).getString ("LBL_header_octave"));
columns.addColumn (column);
column = new TableColumn (2, 150, new PulldownRenderer (Score.DURATIONS_LONG), new PulldownEditor (Score.DURATIONS_LONG));
column.setHeaderValue (NbBundle.getBundle (ScorePanel.class).getString ("LBL_header_duration"));
columns.addColumn (column);
final JTable table = new JTable (new Model (), columns);
removeAll ();
add (new JScrollPane (table), BorderLayout.CENTER);
JButton add = new JButton (NbBundle.getBundle (ScorePanel.class).getString ("LBL_add_row"));
add.addActionListener (new ActionListener () {
public void actionPerformed (ActionEvent ev) {
addRow ();
}
});
final JButton del = new JButton (NbBundle.getBundle (ScorePanel.class).getString ("LBL_remove_row"));
del.setEnabled (false);
del.addActionListener (new ActionListener () {
public void actionPerformed (ActionEvent ev) {
delRows (table.getSelectedRows ());
}
});
table.getSelectionModel ().addListSelectionListener (new ListSelectionListener () {
public void valueChanged (ListSelectionEvent ev) {
del.setEnabled (table.getSelectedRows ().length > 0);
}
});
JPanel buttons = new JPanel ();
FlowLayout layout = new FlowLayout ();
layout.setAlignment (FlowLayout.CENTER);
layout.setHgap (15);
buttons.setLayout (layout);
buttons.add (add);
buttons.add (del);
add (buttons, BorderLayout.SOUTH);
revalidate ();
}
private void addRow () {
int size = score.getSize ();
List tones = new ArrayList (size + 1);
List octaves = new ArrayList (size + 1);
List durations = new ArrayList (size + 1);
for (int i = 0; i < size; i++) {
tones.add (new Integer (score.getTone (i)));
octaves.add (new Integer (score.getOctave (i)));
durations.add (new Integer (score.getDuration (i)));
}
tones.add (new Integer (Score.DEFAULT_TONE));
octaves.add (new Integer (Score.DEFAULT_OCTAVE));
durations.add (new Integer (Score.DEFAULT_DURATION));
try {
cookie.setScore (new Score (tones, octaves, durations));
} catch (IOException ioe) {
TopManager.getDefault ().notifyException (ioe);
}
}
private void delRows (int[] rows) {
int size = score.getSize ();
int size2 = size - rows.length;
List tones = new ArrayList (size2);
List octaves = new ArrayList (size2);
List durations = new ArrayList (size2);
KEEPROW:
for (int i = 0; i < size; i++) {
for (int j = 0; j < rows.length; j++)
if (rows[j] == i)
continue KEEPROW;
tones.add (new Integer (score.getTone (i)));
octaves.add (new Integer (score.getOctave (i)));
durations.add (new Integer (score.getDuration (i)));
}
try {
cookie.setScore (new Score (tones, octaves, durations));
} catch (IOException ioe) {
TopManager.getDefault ().notifyException (ioe);
}
}
private class Model extends AbstractTableModel implements ChangeListener {
public Model () {
cookie.addChangeListener (WeakListener.change (this, cookie));
}
public void stateChanged (ChangeEvent ev) {
try {
score = cookie.getScore ();
fireTableDataChanged ();
} catch (IOException ioe) {
// keep previous Score object instead
TopManager.getDefault ().notifyException (ioe);
}
}
public boolean isCellEditable (int row, int col) {
return true;
}
public int getRowCount () {
return score.getSize ();
}
public int getColumnCount () {
return 3;
}
public Object getValueAt (int row, int column) {
if (column == 0)
return new Integer (score.getTone (row));
else if (column == 1)
return new Integer (score.getOctave (row));
else if (column == 2)
return new Integer (score.getDuration (row));
else
throw new ArrayIndexOutOfBoundsException ();
}
public void setValueAt (Object val, int row, int col) {
if (val.equals (getValueAt (row, col))) {
return;
}
int size = score.getSize ();
List tones = new ArrayList (size);
List octaves = new ArrayList (size);
List durations = new ArrayList (size);
for (int i = 0; i < size; i++) {
Object tone;
if (i == row && col == 0)
tone = val;
else
tone = new Integer (score.getTone (i));
tones.add (tone);
Object octave;
if (i == row && col == 1)
octave = val;
else
octave = new Integer (score.getOctave (i));
octaves.add (octave);
Object duration;
if (i == row && col == 2)
duration = val;
else
duration = new Integer (score.getDuration (i));
durations.add (duration);
}
Score nue = new Score (tones, octaves, durations);
try {
cookie.setScore (nue);
} catch (IOException ioe) {
TopManager.getDefault ().notifyException (ioe);
}
}
}
private static class PulldownRenderer extends DefaultTableCellRenderer {
private String[] tokens;
public PulldownRenderer (String[] tokens) {
this.tokens = tokens;
}
protected void setValue (Object o) {
int index = ((Integer) o).intValue ();
setText (tokens[index]);
}
}
private static class PulldownEditor extends DefaultCellEditor {
public PulldownEditor (String[] tokens) {
super (makeComboBox (tokens));
}
private static JComboBox makeComboBox (final String[] tokens) {
Object[] list = new Object[tokens.length];
for (int i = 0; i < list.length; i++)
list[i] = new Integer (i);
JComboBox combo = new JComboBox (list);
combo.setRenderer (new DefaultListCellRenderer () {
public Component getListCellRendererComponent (JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
int index2 = ((Integer) value).intValue ();
return super.getListCellRendererComponent (list, tokens[index2], index, isSelected, cellHasFocus);
}
});
return combo;
}
}
}